home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 6
/
Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso
/
049a
/
aser25.zip
/
UUE20.ASM
< prev
Wrap
Assembly Source File
|
1991-03-12
|
26KB
|
856 lines
name UUENCODE
page 55,132
title 'UUENCODE.ASM'
;
; UUENCODE.ASM -- UUEncodes a Binary File
;
; Cmd line processing, general layout from UU.ASM by Theodore A. Kaldis
;
;Author: David Kirschbaum
; Toad Hall
; kirsch@usasoc.soc.mil
;Released to Public Domain
;
; To assemble and link this program into the executable UUENCODE.COM:
; (It will NOT run compiled as an .EXE program!)
; MASM UUE;
; LINK UUE;
; (If you just have EXE2BIN:
; EXE2BIN UUE
; REN UUE.BIN UUENCODE.COM (or whatever)
; (If you have Public Domain EXE2COM or equivalent:
; EXE2COM UUE
; REN UUE.COM UUENCODE.COM (or whatever)
; (Delete the bogus .OBJ file.)
Comment ~
v2.0, 10 Mar 91
- Keith Petersen says we have to make other "weird" modes work
in the "begin" line (like "begin 0600 foobar.arc").
Seems to be working in the uudecode. No changes required here
in the uuencode side.
- He also asked for the "no overwrite" protection. Installed from
the xxencode code (but only if NOT STDOUT).
- Never did incorporate some tweaks from Germany because they were
too confused with table-related additions (which was broken in
the uudecode side of the house). Incorporating them now with the
v1.9b comments.
- Keith also found we were doing our "no cmdline entry" handling
backwards: prompting for a filename, and then showing usage only
if no filename entry. Reversing that so we show usage, and THEN
prompt for the filename. All error msgs are going to STDERR
(unless it's a "-?" switch, where I'm sending it out via Svc 9,
to permit redirection).
- Tightened up error messages a bit (to include Svc 9 Int 21H display
for <DOS 2.2 error msg!), common routines, etc.
- Added "-?" for just help, moved usage and <DOS 2.x msgs to buffer space
at program end.
v1.9b, 01 Nov 1989 (TapirSoft Gisbert W.Selke)
- tweaked for speed, or rather, style. No noticeable increase in
overall speed...
- fixed a bug with file names starting with a slash (and no other slashes
in the name) or consisting of one character only (without extension).
v1.9, 29 Jul 89
- Had a strange bug in UUD19.
In the process of fixing that, took a relook at this code
and did a little tweaking.
Toad Hall
v1.8, 5 Jul 89
- Version number bumped to v1.8 (skipping v1.4 thru v1.7)
just to get in synch with the companion uudecode program.
- Thanks to Karl-L. Noell <NOELL%DWIFH1.BITNET@CUNYVM.CUNY.EDU>
for two bug reports:
1 - Target filename prompt bug:
| When I call up UUE12 or UUD17 without filename, a prompt appears:
| Input path/file:
| but answering to that prompt always yields the message
| "Input file error."
Dumb error, fixed.
2 - Excessive uuencoded line length at the 45000-byte input point:
| There is one effect, but it doesn't cause any harm:
| when I uuencode large binary files, the resulting *.UUE always has
| line 1001 3 bytes longer as you'll see from the following cut:
| Line
| 1000: M!)(0A")3S,<EVET'2%/THAT7@AOB$0AIY[+*1@)6S(I<)",-ZPD(\J`JAWPH
| 1001: P1SJAV\VFJ+/YP6:,0$$!-Q]T0J?D3%2F<XHO2V>&.=RN#%OYP!:<(H8\P$9*F"E#
| 1002: M%UA5L3N,TR%C\*86_8E$%!#4(E(JYY.BA$XSJ-.2`72G;K82@GDBQ9YEP"=S
| Obviously it has to do with your "READSIZE 45000" which is reached in
| that line (1000 lines * 45 bytes). Anyway the UUDECODE works fine, I've
| tried it with your UUD12 and with UUDECODE 2.14 . The byte count 'P'
| (instead of 'M') tells us, that there are 3 bytes more in this line.
Karl-L was right .. I should've checked to see if we had a full line
(60 chars) of uuencoded bytes BEFORE we check if our binary buffer's
been used up. That'll insure the full line gets written out as soon
as it becomes full.
The fix seems to be working fine, testing with various odd sized files
(to include monster ones that insure that 45000-byte refill).
Added a little logo at the end (overrun by buffers) just to identify
the program.
~
;v1.3, 9 Nov 88
; - Tightening again.
; BP holds binary character count throughout each line uuencoding.
; Tightened uuencoding algorithm itself (fewer shifts & register shuffling).
; - Bumping prompted input filename input to 80 chars.
; - Different (faster) way of testing:
; (1) if we've hit end of the binary read buffer.
; (2) if we've completed 60 uuencoded output characters.
; - Changing READSIZE to a MOD 3 so we lessen problems from reading
; non-MOD 3 numbers of binary characters (until the LAST read).
; This (and other fixes) finally fixed the problem with 'non-MOD 3'
; sized binary files adding bogus uuencoded bytes to the end.
; - Found (and fixed) new bug: one junk byte sneaking in after a binary
; buffer refill from file read. (Problem was uuencoded buffer overlying
; binary buffer.)
;
;v1.1, 7 Sep 88
; - Provisional compilation .. Set STDOUT to 1 to enable redirection.
; Else it'll use the default "filename.uue" format.
; - Fixed bug in filename parsing (need to find the SECOND '\' when
; stripping paths!
;v1.0, 6 Sep 88
;Hacked together from Kaldis' UU.ASM, the public domain UUENCODE.C,
; UUENCODE.PAS, etc.
;Uses same algorithm (kinda) as the Turbo Pascal UUENCODE.PAS (not the
;C version which does too much bit fiddling).
;
; - The last few uuencoded characters are coming out different from the
; products of UUENCODE.PAS and my Unix mainframe's uuencode. (Actually,
; they're ALL different!) Doesn't seem to matter: .ARC files, when
; uuencoded and then uudecoded again, still check out. Might bite us
; somewhere, but haven't had any problems in lots of tests.
;
; David Kirschbaum
; Toad Hall
; kirsch@usasoc.soc.mil
;-------------------------------------------
LF EQU 10
CR EQU 13
FALSE equ 0
TRUE equ NOT FALSE
READSIZE EQU 45000 ;max bytes for a binary file read.
;Small enough to fit within our
; 64Kb code/data space.
;Size must be an even divisor of 3.
LINELEN EQU 60 ;nr chars in a uuencoded line
STDOUT EQU 0 ;change to non-0 to enable redirection
Cseg SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:Cseg,DS:Cseg, ES:Cseg
org 80H ;PSP cmdline start v1.8
cmd_tail label byte ;v1.8
org 100H
UuEncode PROC near
jmp Start ;jump over data
pr_inp DB CR,LF,'Input path/file: '
PR_INP_LEN EQU $-pr_inp
err_inp DB 'Input file error.'
ERR_INP_LEN EQU $-err_inp
err_out DB 'Output file error.'
ERR_OUT_LEN EQU $-err_out
end_msg DB '`',CR,LF,'end',CR,LF
END_MSG_LEN EQU $-end_msg
no_action db 'No action' ;v2.0
NO_ACTION_LEN EQU $-no_action ;v2.0
exist$ db ' exists! Aborting!' ;v2.0
EXIST$_LEN equ $-exist$ ;v2.0
inp_handle DW 0 ;input file handle
out_handle DW 1 ;output file handle (default StdOut)
read_count DW data_buf ;nr binary bytes read
last_flag db FALSE ;set true when partial read
overwrite db FALSE ;set true if "-o" cmdline switch v2.0
;-------------------------------------------
Start:
; Insure we're DOS 2.0 or above (or handles won't work!)
mov ah,30h ;get DOS version
int 21h
cmp al,2 ;2.0 or above?
jae Chk_Cmd ;yep, ok
mov dx,OFFSET msg_v1 ;'DOS 2.0 or above'
jmp Msg9_Term ;display, terminate (AL=1) v2.0
Msg_Die:
call Say_Error ;write to StdErr, AH unchanged v2.0
jmp Terminate ;terminate v2.0
;-------------------------------------------
;Check our PSP command line for a target filename.
Chk_Cmd:
;v1.8 Moved command line parsing to a separate subroutine
; (since we may have to do it twice)
call Parse_CmdLine ;parse PSP cmdline v1.8
jnc Open_Inp_Fil ;we have input v1.8
;(already AsciiZed) v1.8
;DI -> AsciiZ 0 v1.8
;v1.8 No PSP cmdline input.
; Let's prompt our user:
;v2.0 But first show usage.
mov dx,offset usage$ ;'Usage..' v2.0
mov cx,USAGE_LEN ;msg length v2.0
call Say_Error ;display to STDERR v2.0
mov dx,OFFSET pr_inp ;'Input/file name:' prompt
mov cx,PR_INP_LEN ;nr chars to display
mov bx,2 ;STDERR
mov ah,40H ;write to file/device v2.0
int 21H
;Get user's kbd input
;v1.8 via regular DOS buffered keyboard input call
mov di,offset cmd_tail-1 ;1 byte before PSP cmdline v1.8
mov byte ptr [di],80 ;tell DOS max of 80 chars v1.8
mov dx,di ;DX -> buffer v1.8
mov ah,0AH ;buffered kbd input svc v1.8
int 21H
call Parse_CmdLine ;parse the input
jnc Open_Inp_Fil ;got input (already AsciiZed)
;try to open
;DI -> AsciiZ 0
;v2.0 No user entry at all. Error msg, die.
mov ah,1 ;ERRORLEVEL 1 v2.0
mov dx,offset no_action ;'No action' v2.0
mov cx,NO_ACTION_LEN ;msg length v2.0
jmp Msg_Die ;display, terminate v2.0
;We have an input filename. Open it.
Open_Inp_Fil:
mov dx,offset inp_fil ;input filename buffer
mov si,dx ;remember input filename
;buff start
mov ax,3D00h ;open file
int 21h
jnb Inp_Open ;went ok
jmp Inp_Err ;input file open error, die
;-------------------------------------------
Inp_Open:
mov inp_handle,ax ;save input file handle
;Take input file name (up to file separator) (no paths)
;move "filename.typ" into our uuencoded buffer and write to file.
;First scan for any paths, drives, etc.
;SI -> input filename buffer start
;DI -> the last filename char+1, so we can compute length.
mov cx,di ;last char+1
sub cx,si ;-start = nr chars+1 v2.0
dec di ;adjust to end of string
;We'll start at the end and scan back toward the front.
;Remember, scasb decrements DI even if it finds the scan char,
;so we'll have to adjust after the find.
mov al,'\' ;first scan for paths
std ;going backwards
repne scasb
cld ;set back forward again
jz Found_Path ;DI points to char before '\'
mov di,si ;back to start
cmp byte ptr [di+1],':' ;how about a drive?
jne Name_Start ;nope, use buffer start
;else fall thru and bump di past 'd:'
;DI's now pointing at the REAL target file name starting char
;(past the drive, paths, etc.)
;We first move the original target file name into our uue buffer
;(which is initialized with the "start 644 " characters).
;This uue buffer will be written as the first line of our uuencoded file.
Found_Path:
inc di ;adjust for scasb or 'd:'
inc di
Name_Start:
mov si,di ;move from input name start
mov dx,si ;save starting point a sec
mov di,offset uue_filename ;move to within uue buffer
OutName_Loop:
lodsb ;snarf each char
or al,al ;0 means filename end
jz OutName_Done ;done
stosb ;stuff filename char
jmp OutName_Loop ;keep going
OutName_Done:
mov ax,0A0DH ;get CR/LF
stosw ;stuff it in uuencode buffer
;target file name has now been moved into a starting uuencoded file
;text line (to include CR/LF).
IF STDOUT ;use StdOut redirection
mov cx,di ;ptr to last filename char +1
ELSE ;create 'filename.uue'
push di ;remember that ending psn
;Now to create our output file name: filename.uue
mov si,dx ;SI is PSP target filename start
mov di,offset out_fil ;move to output file name buffer
mov dx,di ;we'll need it here also
Uue_Name_Loop:
lodsb ;snarf each char
or al,al ;0 means filename end
jne Check_Dot ;nope
mov al,'.' ;no file type, so fake it
Check_Dot:
stosb ;stuff name char into output name
cmp al,'.' ;go up to separator
jne Uue_Name_Loop ;not yet
;We've now moved the file name (plus the '.') into our output buffer.
;Time for the type
mov ax,'uu' ;'uue'
stosw ;stuff
mov ax,'e' ;'e', DOS AsciiZ terminator
mov [di],ax ;stuff
;DX has output filename starting ofs.
;ptr to last byte in uue buffer is on the stack.
xor cx,cx ;normal file attrib (R/W)
;v2.0 User asked for output file overwrite protection.
; Ok .. let's check for output filename existence
; before we create it.
; DX -> AsciiZ filename
cmp overwrite,TRUE ;'-o' cmdline switch?
jz Out_Create ;that's right, overwrite if exists
mov ah,4EH ;find first
int 21H
cmp al,2 ;file not found?
jz Out_Create ;fine, create it
cmp al,18 ;no more files to be found?
jz Out_Create ;fine, create it
;File exists, so we'll message and abort.
pop cx ;clear stack
mov cx,di ;last char in output name
sub cx,dx ;last -first = length
mov bx,2 ;STDERR
add cx,bx ;adjust count
mov ah,40H ;write to file/device
int 21H
mov dx,offset exist$ ;' exists! Aborting!'
mov cx,EXIST$_LEN ;msg length
mov al,5 ;fake "Access denied" errorlevel
jmp Msg_Die ;display, terminate
Out_Create:
mov ah,3CH ;create file
int 21H
pop cx ;restore uue ptr into CX
jnb Create_Ok ;ok
jmp Out_Err ;'Output file error', die
Create_Ok:
mov out_handle,ax ;save output handle
ENDIF ;StdOut or filename.uue
mov dx,offset uue_out ;'start 644 filename.typ', CR/LF
sub cx,dx ;last char-buff start = bytes to write
call Write_File ;write that record
;Write_File set DI to offset uue_out+1,BP=0
Comment ~ Replaced with Gisbert's v1.9b code
Read_Loop:
CALL Read_File ;do the initial binary read
jz Write_Uue_End ;nothing read, done with input
;Read_File set SI to offset data_buf, didn't touch DI output buffer ptr,
;or BP binary byte counter.
Uue_Loop:
;SI and BP are incrementing as we uuencode 45 bytes of binary data
;into 60 bytes of 'ready to Asciify' data.
mov cx,0604H ;handy constant
;CL=4,CH=6
lodsb ;hunk[1]
mov ah,al ;AH, AL=hunk[1]
shr al,1 ;quad[1] = hunk[1] SHR 2
shr al,1 ;(faster this way)
stosb ;= quad[1], stuff
lodsb ;AL=hunk[2]
mov dl,al ;save hunk[2] a sec
shl ah,cl ;hunk[1] SHL 4
shr al,cl ;hunk[2] SHR 4
add al,ah ;shifted hunk[1]+shifted hunk[2]
stosb ;= quad[2], stuff
mov ah,dl ;AH=orig hunk[2]
lodsb ;AL=hunk[3]
mov dl,al ;save hunk[3] in DL a sec
shl ah,1 ;hunk[2] SHL 2
shl ah,1 ;(faster this way)
mov cl,ch ;CL now 6
shr al,cl ;hunk[3] SHR 6
add al,ah ;shifted hunk[2]+shifted hunk[3]
stosb ;= quad[3], stuff
mov al,dl ;AL=orig hunk[3]
stosb ;= quad[4], stuff
;That 3-byte hunk is done. See if our binary buffer's empty.
;Notice we ALWAYS assume we did all 3 binary bytes.
;If we didn't (e.g., had a non-MOD 3 nr of binary bytes in our file),
;we'll correct that later with an adjustment to the binary counter
;character in the uuencoded line.
add bp,3 ;+3
;v1.8 Trying to work around that "extra 4 chars"
; written to output at the 45000-byte buffer end.
; To do this, we first check to see if our uuencoded output line
; is full yet (e.g., 45 binary bytes read, 64 uuencoded chars
; ready to be output):
cmp bp,45 ;done a line of binary data yet? v1.8
jnz Chk_BuffEnd ;nope v1.8
call Write_Uue ;stuff binary count in record, v1.8
;Asciify entire record,
;append CR/LF, write to file
;Reset BP binary counter=0,
;DI back to output buffer start +1
Chk_BuffEnd: ; v1.8
cmp si,read_count ;hit data end yet?
jb Uue_Loop ;nope,not yet v1.8
;keep uuencoding input buffer v1.8
cmp last_flag,1 ;Was last read the binary file EOF?
jne Read_Loop ;nope, do another read, maybe end.
;-------------------------------------------
Comment ends ~
;v1.9b New Code
Read_Loop:
CALL Read_File ;do the initial binary read
jz Write_Uue_End ;nothing read, done with input
mov cl,6 ;handy constant v1.9b
;Read_File set SI to offset data_buf, didn't touch DI output buffer ptr,
;or BP binary byte counter.
Uue_Loop:
;SI and BP are incrementing as we uuencode 45 bytes of binary data
;into 60 bytes of 'ready to Asciify' data.
lodsb ;hunk[1]
mov ah,al ;AH, AL=hunk[1]
shr al,1 ;quad[1] = hunk[1] SHR 2
shr al,1 ;(faster this way)
stosb ;= quad[1], stuff
lodsb ;AL=hunk[2]
mov dl,al ;save hunk[2] a sec
shr ax,1 ;combine low 2 bits of hunk[1] v1.9b
shr ax,1 ;and high 4 bits of hunk[2] v1.9b
shr ax,1 ;(4 single shifts are still v1.9b
shr ax,1 ;faster than one shift by CL) v1.9b
stosb ;= quad[2], stuff
mov ah,dl ;AH=orig hunk[2]
lodsb ;AL=hunk[3]
mov dl,al ;save hunk[3] in DL a sec
shr ax,cl ;hunk[2] SHL 2 OR hunk[3] SHR 6 v1.9b
stosb ;= quad[3], stuff
mov al,dl ;AL=orig hunk[3]
stosb ;= quad[4], stuff
;That 3-byte hunk is done. See if our binary buffer's empty.
;Notice we ALWAYS assume we did all 3 binary bytes.
;If we didn't (e.g., had a non-MOD 3 nr of binary bytes in our file),
;we'll correct that later with an adjustment to the binary counter
;character in the uuencoded line.
add bp,3 ;+3
;v1.8 Trying to work around that "extra 4 chars"
; written to output at the 45000-byte buffer end.
; To do this, we first check to see if our uuencoded output line
; is full yet (e.g., 45 binary bytes read, 64 uuencoded chars
; ready to be output):
cmp bp,45 ;done a line of binary data yet? v1.8
jnz Chk_BuffEnd ;nope v1.8
call Write_Uue ;stuff binary count in record, v1.8
;Asciify entire record,
;append CR/LF, write to file
;Reset BP binary counter=0,
;DI back to output buffer start +1
mov cl, 6 ;restore handy constant v1.9b
Chk_BuffEnd: ; v1.8
cmp si,read_count ;hit data end yet?
jb Uue_Loop ;nope,not yet v1.8
;keep uuencoding input buffer v1.8
cmp last_flag,1 ;Was last read the binary file EOF?
jne Read_Loop ;nope, do another read, maybe end.
;-------------------------------------------
Write_Uue_End:
or bp,bp ;any bytes uuencoded?
jz No_Partial_Write ;none, so no trailing to write
;In converting 3 binary bytes to 4 quad chars, we may have bumped SI
;beyond the actual number of binary bytes read.
;By subtracting the original count of bytes read from SI,
;we'll get the number of 'bogus' binary bytes in that last quad.
;Subtract that from the BP binary counter, and we'll get the TRUE
;number of binary bytes in that uuencoded line.
;It's up to the uudecoding program to catch that difference
;and ignore the extra quads. (The ones I've tested seem to.)
sub si,read_count ;check for overrun
sub bp,si ;subtract any bogus bytes
call Write_Uue ;write partial line
No_Partial_Write:
mov dx,offset end_msg ;'end',CR/LF
mov cx,END_MSG_LEN ;nr bytes to move
call Write_File ;do the last write
;DOS closes open files at termination.
;However, just to be neat:
IF NOT STDOUT ;no StdOut
mov bx,out_handle ;output file handle
mov ah,3EH ;close the file
int 21H
ENDIF
Terminate:
mov ah,4Ch ;terminate, ERRORLEVEL ?
int 21h
;v2.0 Enter here for a msg display via svc 9, Int 21H
; (msg address in DX)
Msg9_Term:
push ax ;save errorlevel
mov ah,9
int 21H
pop ax ;restore
jmp Terminate
UuEncode endp
;-------------------------------------------
Write_Uue PROC NEAR
;Enter with DI pointing to char beyond last uuencoded char.
;Stuff CR/LF, compute line length, write to file.
;v1.9 push si ;save input ptr a sec
MOV DX,offset uue_out ;output line start (length byte)
mov cx,di ;current output pointer
sub cx,dx ;- buffer start = nr bytes in line
;+1, but that's ok since we're adding
;the line_len byte
push cx ;save full line length for later
;Do the last masking of the line of quads
;v1.9 mov si,dx ;point to line start for 'from'
mov di,dx ;moving to same place
mov ax,bp ;binary bytes in this line
;v1.9 mov [si],al ;stuff binary length byte
mov [di],al ;stuff binary length byte v1.9
; (uuencode later)
mov ah,20H ;get a handy constant
;Gotta process every byte, masking, checking for spaces, etc.
;This includes that length byte.
mov bx,(3FH SHL 8) + 96 ;get another handy constant
;BH=3FH, BL=96
Mask_Loop:
; lodsb ;get output line char
mov al,[di] ;get output line char v1.9
and al,bh ;3FH ;six-bit mask
add al,ah ;plus asciifying offset
cmp al,ah ;end up with a space
jne Not_Space ;nope
mov al,bl ;96 ;use space substitute "`"
Not_Space:
stosb ;stuff it back in line buffer
loop Mask_Loop ;do them all
pop cx ;restore char count for bytes to write
;DI now points at char just beyond uuencoded char line
mov ax,0A0DH ;Get CR/LF
mov [di],ax ;stuff them in buffer
inc cx ;add in CR/LF to length
inc cx
;v1.9 pop si ;restore SI
Write_File:
MOV BX,out_handle ;output file handle
MOV AH,40h ;write to file/device
INT 21h
jb Out_Err ;write error
mov di,dx ;point DI back to uue_out start
inc di ;bump past length byte
xor bp,bp ;reset byte ctr
RET ;write done
;Output file write error
Out_Err:
MOV DX,OFFSET err_out ;'Output file error'
MOV CX,ERR_OUT_LEN ;msg length
jmp short Fatal_Error ;common code
Write_Uue ENDP
;-------------------------------------------
;Read a chunk of raw binary data
Read_File PROC NEAR
MOV DX,offset data_buf ;into binary input buffer
mov cx,READSIZE ;nr bytes to read
MOV BX,inp_handle ;input file handle
MOV AH,3Fh ;read from file/device
INT 21h
jb Inp_Err ;failed
;AX has nr of bytes read
mov si,dx ;SI needs offset data_buf
mov bx,dx ;buffer start
add bx,ax ;+bytes read = data end
;BX points to the next 'empty' byte (data_buf start + bytes read)
cmp ax,cx ;read a full buffer?
je Read_Full ;yep, no fiddling required
;We've read less than a buffer full. Let's make sure the last bytes
;are nulls if bytes read are not MOD 3.
mov word ptr [bx],0 ;stuff 2 nulls there
mov last_flag,1 ;turn EOF flag on
Read_Full:
mov read_count,bx ;point to data end
or ax,ax ;set flags for return
RET ;read done
;-------------------------------------------
;Input file read error. Error value in AL
Inp_Err:
MOV DX,OFFSET err_inp ;'Input file error'
MOV CX,ERR_INP_LEN ;msg length
;Common code added here
Fatal_Error:
call Say_Error ;display error msg, AL unchanged v2.0
jmp Terminate ;terminate v2.0
Read_File ENDP
;-------------------------------------------
Say_Error proc near
;DX -> error msg
;CX = msg len
push ax ;save AX v2.0
push dx ;msg address v2.0
push cx ;msg length
mov dx,offset crlf ;precede msgs w/CRLF
mov cx,CRLF_LEN ;length
call ErrOut ;display it
pop cx ;restore
pop dx ; original error msg
call ErrOut ;display it
mov dx,offset crlf ;precede msgs w/CRLF
mov cx,CRLF_LEN ;length
call ErrOut ;display it
pop ax ;restore AX (error level maybe)
ret
ErrOut: mov bx,2 ;Std ErrOut handle
mov ah,40h ;write to file/device
int 21h
ret
Say_Error ENDP
;v1.8 Command line processing subroutine
Parse_CmdLine proc near
MOV SI,offset cmd_tail ;move cmd line parm v1.8
MOV DI,offset inp_fil ;to our filename buffer
CLD ;insure fwd
LODSB ;cmd line length byte
or al,al ;nothing there?
jz PC_NoInput ;yep, nothing there
mov ah,20H ;get a handy space
Strip_Ct:
lodsb ;next cmd line char
cmp al,ah ;gobble leading spaces,tabs, etc.
jbe Strip_Ct
;v2.0 Check for a "-o" switch on command line
cmp al,'/' ;this kind of switch?
jz GotSwitch ;yep
cmp al,'-' ;switch?
jnz NotSwitch ;nope, must be name char
GotSwitch:
mov dx,ax ;save this char a second
mov ax,[si] ;snarf next 2 chars
cmp al,'?' ;Wants help? v2.0
jz JustHelp ;yep, help, die v2.0
and al,5FH ;mask 1st char to uppercase
cmp ax,' O' ;O and space means switch
mov ax,dx ;restore in case not
jnz NotSwitch ;nope, must be name
;We have the overwrite switch
not overwrite ;toggle flag to TRUE
inc si ;bump past 'o'
inc si ;and past space
lodsb ;next char should be name
Ct_Char:
cmp al,ah ;ctrl char? (e.g., CR)
jbe PC_Input ;yep, done
NotSwitch:
stosb ;stuff filename byte
lodsb ;snarf next cmdline char
jmp Ct_Char ;and loop
PC_NoInput:
stc ;no input, return CF set
ret
PC_Input:
mov byte ptr [di],0 ;Asciize filename input
clc ;got input, return CF clear
ret
;v2.0 New code
JustHelp:
pop ax ;clear original call to be neat
mov dx,offset usage$ ;'Usage:'
mov al,1 ;ERRORLEVEL 1
IF STDOUT
;With output going to STDOUT, we'd better send usage to STDERR
mov cx,USAGE_LEN ;msg length
jmp Fatal_Error ;display STDERR, terminate
ELSE
jmp Msg9_Term ;display via Svc 9, terminate
ENDIF
Parse_CmdLine endp
;using pointers here at code end for various buffers.
;the uue_out buffer is normally 60 uuencoded chars, plus CR/LF
;It's initialized with the default uuencode file header.
;No, I don't know the magic in '644'.
EVEN ;v1.2
uue_out db 'begin 644 ' ;first write contains this + name
;The rest of these buffers don't take any code space.
uue_filename equ $ ;where we move filename.uue
;Leave room for LINELEN+2 chars for uue_out buffer.
inp_fil equ uue_out + LINELEN +2 ;80 chars long
;Leave room for 80 chars for inp_fil filename buffer.
out_fil equ inp_fil + 80 ;15 bytes long
data_buf equ out_fil ;leave room for uue_out
logo db 'UUENCODE v2.0',0 ;v2.0
db 'David P Kirschbaum, Toad Hall, '
db 'Given to the public domain',0
IF STDOUT
usage$ db 'UUENCODE [d:][\path\]binary.fil [>output] <RETURN>'
db CR,LF,'(Uses redirection)'
ELSE
usage$ db 'UUENCODE [-o] [d:][\path\]binary.fil <RETURN>',CR,LF
db 'produces binary.UUE on current drive\path',CR,LF
db '(providing binary.UUE doesn''t already exist).',CR,LF ;v2.0
db '-o switch forces overwrite of existing binary.UUE' ;v2.0
ENDIF
USAGE_LEN equ $-usage$ ;v2.0
db CR,LF,'$' ;for Svc 9 display v2.0
msg_v1 DB 'This program requires DOS V2.0 or higher.'
crlf db CR,LF ;v2.0
CRLF_LEN EQU $-crlf ;v2.0
db '$' ;Svc 9 display only v2.0
Cseg ENDS
END UuEncode